#include "viewer.h"
#include "ui_viewer.h"

viewer::viewer(QSerialPort *_port,QWidget *parent) :   
    QWidget(parent),
    ui(new Ui::viewer),
    m_port(_port)
{
    ui->setupUi(this);
    m_RXDataSize = 0;             /*计算接收数据的大小*/
    m_TXDataSize = 0;             /*计算发送数据的大小*/
    m_flag = 1;//1是只有一个框

    //UI切换
    UISwitch();

    /*connect*/

    /*接收数据*/
    //init QTimer
    m_timer = new QTimer(this);
    connect(m_timer,&QTimer::timeout,this,&viewer::recvOver);

    //接收到数据开始计时
    connect(m_port,&QSerialPort::readyRead,[=](){

//        if(m_rxDataChar.size() == 0)
//        {
//            m_timer->start(1000);
//        }

//    connect(this,&viewer::sendSignal,[=](){
        //m_timer->start(3000);//×××不可以用这信号处理 此时readport为空
        QByteArray bytearray = m_port->readAll();

        //int baSize = bytearray.size();
        //qDebug()<<"received"<<baSize<<"Byte :"<<bytearray;

        m_rxDataChar.append(bytearray);

        bytearray = bytearray.toHex();
        //qDebug()<<"Data:"<<bytearray<<"size:"<<m_rxDataHex.size();


        //集合数据
        m_rxDataHex.append(bytearray);

//        QString ret;
//        for (int i = 0; i < m_rxDataChar.count(); ++i)
//        {
//               ret.append( tr("0x%1,").arg((quint8)m_rxDataChar.at(i),2,16,QLatin1Char('0')).toUpper());
//        }
//        qDebug()<<ret;

        //check frame here
        //if(this->analyseFrame()) //nocheck
        {
            //m_timer->stop();
            qDebug()<<"not time out";
            //recv over
            //this->recvOver();

            emit data_print(bytearray);
        }
        // else time out -> recv over

    });

}

viewer::~viewer()
{
    delete ui;
    delete m_port;
}


/**
 * @breif serial port is send ok?
 * @para
 * @return
*/
bool viewer::IsSendOver()
{
    QByteArray send_data = m_port->readLine();
    return send_data.isEmpty();
}
//breif 给m_viewer内部的端口发送 QByteArrary数据
//para ba要发送到内部端口的数据
//return 返回发送成功的字节数 -1表示失败
int viewer::send2Port(QByteArray ba)
{

    //发送
    m_port->QSerialPort::open(QIODevice::ReadWrite);
    int sendNum = m_port->write(ba);
    if(sendNum != ba.size())
    {
        QMessageBox::information(this,"警告","无法访问端口！");
    }

    //display
    QDateTime time = QDateTime::currentDateTime();
    QString currentTime = time.toString(Qt::ISODate);
    ui->textEdit_TxData->append(currentTime);

    if(m_flag == DISPLAY_MODE_0)
    {
        ui->textEdit_TxData->insertPlainText("Send:");
    }

    ba = ba.toHex();
    ui->textEdit_TxData->append(ba);

    //发送数据开始计时
    //m_timer->start(3000);
    return sendNum;
}

int viewer::send2Port(QString str)
{
    QByteArray ba = str.toLatin1();
    //发送
    return viewer::send2Port(ba);
}


void viewer::UIRxUpdate(QByteArray ba)
{
//    ui->textEdit_TxData->clear();
    ba = ba.toHex();
//    QString currentTime = QDateTime::currentDateTime().toString(Qt::ISODate);
//    ui->textEdit_TxData->insertPlainText(currentTime);
    ui->textEdit_RxData->append(ba);

}

void viewer::UIRxUpdate(QString qstr)
{
    ui->textEdit_RxData->append(qstr);
}

void viewer::UISwitch()
{
    if(m_flag == DISPLAY_MODE_1)
    {
        ui->label_TxData->setText("接收：");
        ui->textEdit_RxData->resize(ui->textEdit_RxData->width(),ui->textEdit_RxData->height()*2);
        ui->label_TxData->hide();
        ui->textEdit_TxData->hide();
        ui->pushButton_Trans->hide();
        m_flag = DISPLAY_MODE_0;
    }
    else
    {
        ui->label_TxData->setText("发送区");
        ui->textEdit_RxData->resize(ui->textEdit_RxData->width(),ui->textEdit_RxData->height()*(1/2));
        ui->label_TxData->show();
        ui->textEdit_TxData->show();
        ui->pushButton_Trans->show();
        m_flag = DISPLAY_MODE_1;
    }
}

int viewer::analyseFrame()
{
    ////7817 20241301 zzd这里协议解析应该放到协议中去
    int head_pos = 0;
    int index = 1;

    if(m_rxDataChar.size() < 9)
        return 0;
    for(int i = 0; i< m_rxDataChar.count(); i++)
    {
        if(m_rxDataChar.at(i) == 0x78)
        {
            head_pos = i;
            break;
        }
        if(i == m_rxDataChar.count())
        {
            qDebug()<<"frame check error :cant find head";
            return 0;//找到最后一个没找到
        }
    }

    if(head_pos + 9 > m_rxDataChar.count())
     {
        qDebug()<<"frame check error: too short";
        return 0 ;
     }

    //madr
    index += head_pos;
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    int len = (m_rxDataChar.at(index++) & 0x1F);// + 1 & 0xFFFF;
    index += len;

    //yadr
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    len = (m_rxDataChar.at(index++) & 0x1F);// + (1 & 0xFFFF);
    index += len;

    //frame counter
    index++;

    //cmd
    index++;

    //data len
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    char data_len1 = m_rxDataChar.at(index++);
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    char data_len2 = m_rxDataChar.at(index++);
    len = (data_len1 << 8) + data_len2;

    //data
    QByteArray frame_data;
    for(int i = index ; i < index + len; i++)
    {
        frame_data.append(m_rxDataChar.at(i));
    }
    index += len;

    //emit signal?

    //cs
    char sum = 0;
    for(int i = head_pos; i < index; i++)
    {
        sum += m_rxDataChar.at(i);
    }
    sum = sum % 256;
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    char cs = m_rxDataChar.at(index);
    if(m_rxDataChar.at(index++) != sum)
    {
        qDebug()<<cs;
        qDebug()<<sum;
        qDebug()<<"frame check error: check sum err";
        return 0;
    }

    //end
    if(index > m_rxDataChar.count())
    {
        return 0;
    }
    if(m_rxDataChar.at(index) != 0x17)
    {
        qDebug()<<"frame check error: end error";
        return 0;
    }
    emit data_print(frame_data);

    return 1;
}



/*slot func*/

/*transmission*/
void viewer::on_pushButton_Trans_clicked()
{
    QString data = ui->textEdit_TxData->toPlainText();
    QByteArray bytearray = data.toLatin1();
    int ret = send2Port(bytearray);
    if(ret < 0)
    {
        //qDebug()<<"send failed in on_pushButton_Trans_clicked";
        return ;
    }


    qDebug()<<"tx:"<<bytearray;

}

/*clear*/

void viewer::on_pushButton_Clear_clicked()
{
    ui->textEdit_TxData->clear();
    ui->textEdit_RxData->clear();

}

void viewer::on_pushButton_swtich_clicked()
{
    UISwitch();
}

//接收结束 UI显示时间+数据
void viewer::recvOver()
{
    //UI operate
    //time
    QString currentTime = QDateTime::currentDateTime().toString(Qt::ISODate);
    QString stringtime = QString("[%1]").arg(currentTime);
    ui->textEdit_RxData->insertPlainText(stringtime);

    //text
    //ui->textEdit_RxData->append(m_rxDataHex);
    //special handler
    QString rxdata_str;
    for (int i = 0; i < m_rxDataHex.count(); ++i)
    {
        rxdata_str.append( tr("%1").arg(m_rxDataHex.toUpper().at(i)));
        if(i%2)
            rxdata_str.append(" ");
    }
    //qDebug()<<rxdata_str;
    ui->textEdit_RxData->insertPlainText(rxdata_str);

    ui->textEdit_RxData->append("");

    //rxdata clear
    m_rxDataHex.clear();
    m_rxDataChar.clear();
    qDebug()<<"recvover!!";

    if(m_timer->isActive())
    {
        m_timer->stop();
        this->analyseFrame();
        qDebug()<<"time out";
    }
}
